package org.zoomdev.zoom.dao.transaction;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zoomdev.zoom.dao.DaoException;
import org.zoomdev.zoom.dao.modules.CoreDaoModule;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public final class Transactions {


    private static final Logger log = LoggerFactory.getLogger(CoreDaoModule.NAME);
    private final TransactionLevel level;
    private final List<Transaction> transactions = new ArrayList<>();
    private int refCount;

    public Transactions(TransactionLevel level) {
        this.level = level;
        this.refCount = 1;
    }

    public int getRefCount() {
        return refCount;
    }


//    public void commit() {
//        if (0 == subRefCount()) {
//            try {
//                _commit();
//            } finally {
//                remove();
//            }
//        }
//    }
//
//    public void rollback() {
//        if (0 == subRefCount()) {
//            try {
//                _rollback();
//            } finally {
//                remove();
//            }
//        }
//    }

//    public static void commit() {
//        Transactions transactions = get();
//        if (transactions != null) {
//            if (0 == transactions.subRefCount()) {
//                try {
//                    transactions._commit();
//                } finally {
//                    remove();
//                }
//            }
//        }
//    }

//    public static void rollback() {
//        Transactions transactions = get();
//        if (transactions != null) {
//            if (0 == transactions.subRefCount()) {
//                try {
//                    transactions._rollback();
//                } finally {
//                    remove();
//                }
//            }
//        }
//    }


    public void addRefCount() {
        ++refCount;
    }

    public int subRefCount() {
        return --refCount;
    }

    public void _commit() {

        try {
            for (Transaction transaction : transactions) {
                try {
                    transaction.commit();
                } catch (Throwable e) {
                    //失败
                    log.error("Error while commit", e);
                    throw new DaoException(e);
                }
            }
        } finally {
            clean();
        }

    }

    public void _rollback() {
        try {
            for (Transaction transaction : transactions) {
                try {
                    transaction.rollback();
                } catch (Throwable e) {
                    log.error("Error while rollback", e);
                    throw new DaoException(e);
                }

            }
        } finally {
            clean();
        }

    }

    public Connection openConnection(DataSource dataSource) throws SQLException {
        final List<Transaction> transactions = this.transactions;

        for (Transaction transaction : transactions) {
            if (transaction.dataSource == dataSource) {
                return transaction.getConnection();
            }
        }
        Transaction transaction = new Transaction(level.ordinal(), dataSource);
        transactions.add(transaction);
        return transaction.getConnection();
    }

    private void clean() {
        for (Transaction transaction : transactions) {
            transaction.clean();
        }
        transactions.clear();
    }


}
